﻿using DevelopAssistant.AddIn.JavaProject.Properties;
using DevelopAssistant.Common;
using DevelopAssistant.Service;
using ICSharpCode.WinFormsUI.Controls;
using ICSharpCode.WinFormsUI.Theme;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace DevelopAssistant.AddIn.JavaProject
{
    public partial class MainForm : ICSharpCode.WinFormsUI.Forms.BaseForm
    {       
        private string NodeName;
        private string ThemeName;

        private DataTable tableObject = null;

        private ProjectCodeForm springBootProjectCode = null;

        DevelopAssistant.Core.MainForm mainform = null;
        DevelopAssistant.Service.DataBaseServer server = null;

        public MainForm(DevelopAssistant.Core.MainForm form, AddInBase addin, NTreeNode node,
            DevelopAssistant.Service.DataBaseServer server,
            string theme,string editorTheme)
        {
            InitializeComponent();
            InitializeControls(theme, node.Text);          
            this.mainform = (DevelopAssistant.Core.MainForm)form;
            this.server = (DevelopAssistant.Service.DataBaseServer)server;
        }

        private void InitializeControls(string theme,string nodeText)
        {
            this.ThemeName = theme;
            this.NodeName = nodeText;            

            ListItem item = null;
            item = new ListItem();
            item.Text = "DbTypes.Sql";
            item.Value = "Sql";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.PostgreSql";
            item.Value = "PostgreSql";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.Oracle";
            item.Value = "Oracle";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.MySql";
            item.Value = "MySql";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.OleDb";
            item.Value = "OleDb";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.SqlLite";
            item.Value = "SqlLite";
            combTypes.Items.Add(item);

            combTypes.SelectedIndex = 0;

            lblStateMsg.Text = "";

            WinFormsUIThemeBase themeBase = new ThemeMac();
            switch (ThemeName)
            {
                case "Mac":
                    themeBase = new ThemeMac();
                    break;
                case "Shadow":
                    themeBase = new ThemeShadow();
                    break;
                case "VS2012":
                    themeBase = new ThemeVS2012();
                    break;
            }
            XTheme = themeBase;

            this.btnApplyOk.Focus();
            this.txtNameSpace.Text = "spring.code.example";
            this.txtModelpath.Text = "demo";
            this.txtTableName.Text = NodeName;
            this.Text = "表 " + NodeName + " 生成项目代码";
            this.panel1.BorderColor = themeBase.FormBorderOutterColor;

        }        

        private void MainForm_Load(object sender, EventArgs e)
        {
            OnThemeChanged(new EventArgs());
            LoadBindData();
        }

        private void LoadBindData()
        {
            listView1.PerformLayout();
            listView1.BeginUpdate();

            this.listView1.Columns.AddRange(new NColumnHeader[]{
               new NColumnHeader(){ Name ="名称", Text ="名称", Width =120 },
               new NColumnHeader(){ Name ="数据类型", Text ="数据类型", Width =140 },
               new NColumnHeader(){ Name ="标识", Text ="标识", Width =120 },
               new NColumnHeader(){ Name ="描述", Text ="描述", Width =100 }
            });

            using (var db = Utility.GetAdohelper(server))
            {
                DataTable table = tableObject = db.GetTableObject(NodeName);
                foreach (DataRow row in table.Rows)
                {
                    string columnName = row["ColumnName"] + "";
                    string typeName = row["TypeName"] + "";
                    string cisnull = row["CisNull"] + "";
                    string length = row["Length"] + "";
                    string describ = row["Describ"] + "";

                    cisnull = cisnull.Trim(',');

                    NListViewItem item = new NListViewItem(
                        new string[] { columnName, SnippetBase.getDataBaseDataType(typeName, length, server.ProviderName), cisnull, describ });
                    item.Text = columnName;
                    item.Name = columnName;

                    if (cisnull.Contains("pk"))
                    {
                        item.StateImageIndex = 0;
                        this.txtPKey.Text = columnName;
                    }
                    else
                    {
                        item.StateImageIndex = 1;
                    }

                    this.listView1.Items.Add(item);
                }
            }

            listView1.EndUpdate();
            listView1.ResumeLayout();

        }

        private GenerateSettings GetSettings()
        {
            GenerateSettings settings = new GenerateSettings();
            settings.CamelCase = checkBox2.Checked;
            settings.ParamaryKey = txtPKey.Text;
            settings.NameSpace = txtNameSpace.Text;
            settings.Modelpath = txtModelpath.Text;
            settings.DataBaseType = ((ListItem)combTypes.SelectedItem).Value;
            return settings;
        }

        private async void btnApplyOk_Click(object sender, EventArgs e)
        {
            try
            {
                List<RequestEntity> list = new List<RequestEntity>();
                foreach (CheckBox checkBox in groupBox3.Controls)
                {
                    if (checkBox.Checked)
                    {
                        RequestEntity requestEntity = new RequestEntity(checkBox.Text, checkBox.Text);                                        
                        list.Add(requestEntity);
                    }
                }

                if (list.Count == 0)
                {                  
                    DevelopAssistant.Core.ToolBox.MessageDialog messageDialog = new DevelopAssistant.Core.ToolBox.MessageDialog(Resources.tip_32px, "请选择要生成的代码类型!", MessageBoxButtons.OKCancel);
                    messageDialog.ShowDialog(this);
                    return;
                }

                string tableName = this.txtTableName.Text;

                springBootProjectCode = (ProjectCodeForm)mainform.AddNewContent(new ProjectCodeForm(this, ThemeName, AppSettings.EditorSettings.TSQLEditorTheme), "表 " + tableName + " 项目代码");
                springBootProjectCode.StartSnipperList(list);

                GenerateSettings settings = GetSettings();
                var result = await AsyncGenerateCode(tableName, settings, list, ReportProgressValue);

                this.lblStateMsg.Text = "生成代码完成";
                this.progressBar1.Visible = false;
                this.label6.Visible = false;
                this.panel3.Visible = false;

                springBootProjectCode.FinishSnipperList();               

            }
            catch(Exception ex)
            {
                this.panel3.Visible = false;
                txtOutMsg.AppendText(ex.Message + System.Environment.NewLine);
                DevelopAssistant.Common.NLogger.WriteToLine(ex.Message, "Error", DateTime.Now, ex.Source, ex.StackTrace);
            }
        }        

        private void btnCancle_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private async System.Threading.Tasks.Task<List<ResultEntity>> AsyncGenerateCode(string tableName, GenerateSettings settings, List<RequestEntity> list, Action<ReportProgressValueEventArgent> action)
        {
            var result = await System.Threading.Tasks.Task<List<ResultEntity>>.Run(() => {
                var response= JavaSpringBootHelper.GenerateCode(tableName, settings, tableObject, list, action);
                System.Threading.Thread.Sleep(500);
                return response;
            });
            return result;
        }

        private void ReportProgressValue(ReportProgressValueEventArgent e)
        {
            this.Invoke(new MethodInvoker(delegate () {
                txtOutMsg.AppendText(e.Message + System.Environment.NewLine);
                lblStateMsg.Text = e.Message;
                if(e.State== ReportProgressState.processing)
                {
                    springBootProjectCode.OnSnipperDataBind(e.Data);
                    this.progressBar1.Value = (int)e.ProgressValue;
                }            
            }));
        }

        public void OnThemeChanged(EventArgs e)
        {
            Color foreColor = SystemColors.WindowText;
            Color backColor = SystemColors.Control;
            Color linkColor = System.Drawing.Color.Blue;
            Color textBackColor = SystemColors.Window;
            Color toolBackColor = SystemColors.Control;
            Color progressBackColor = SystemColors.ControlLight;
            string themeName = AppSettings.EditorSettings.TSQLEditorTheme;
            switch (themeName)
            {
                case "Default":
                    foreColor = SystemColors.WindowText;
                    backColor = SystemColors.Control;
                    linkColor = System.Drawing.Color.Blue;
                    textBackColor = SystemColors.Window;
                    toolBackColor = SystemColors.Control;
                    progressBackColor = SystemColors.ControlLight;
                    break;
                case "Black":
                    foreColor = Color.FromArgb(250, 250, 250);
                    backColor = Color.FromArgb(045, 045, 048);
                    linkColor = Color.FromArgb(051, 153, 153);
                    textBackColor = Color.FromArgb(038, 038, 038);
                    toolBackColor = Color.FromArgb(038, 038, 038);
                    progressBackColor = Color.FromArgb(045, 045, 048);
                    break;
            }

            txtTableName.XForeColor = foreColor;
            txtTableName.XBackColor = textBackColor;
            txtModelpath.XForeColor = foreColor;
            txtModelpath.XBackColor = textBackColor;
            txtPKey.XForeColor = foreColor;
            txtPKey.XBackColor = textBackColor;
            txtNameSpace.XForeColor = foreColor;
            txtNameSpace.XBackColor = textBackColor;
            txtOutMsg.XForeColor = foreColor;
            txtOutMsg.XBackColor = textBackColor;
            btnApplyOk.ForeColor = foreColor;
            btnApplyOk.BackColor = toolBackColor;
            btnCancle.ForeColor = foreColor;
            btnCancle.BackColor = toolBackColor;
            panel1.ForeColor = foreColor;
            panel1.BackColor = toolBackColor;
            panel2.ForeColor = foreColor;
            panel2.BackColor = toolBackColor;
            panel3.ForeColor = foreColor;
            panel3.BackColor = toolBackColor;
            panel4.ForeColor = foreColor;
            panel4.BackColor = backColor;
            combTypes.ForeColor = foreColor;
            combTypes.BackColor = backColor;
            progressBar1.ForeColor = foreColor;
            progressBar1.BackColor = backColor;
            progressBar1.BaseColor = progressBackColor;

            this.listView1.SetTheme(themeName);
        }

    }
}
